using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace Home.PC.Tools
{
    public sealed class DirectoryTreeFlattener : ITool
    {
        private const ToolType _toolType = ToolType.DirectoryTreeFlattener;
        private const string _name = "Directory Tree Flattener";
        private const string _description = "Flattens a directory structure under the source directory.";

        private DirectoryInfo _sourceDirectory;
        private DirectoryInfo _destinationDirectory;
        private bool _moveContent;
        private string _subdirectorySeparator;

        public DirectoryInfo SourceDirectory
        {
            get { return _sourceDirectory; }
            set { _sourceDirectory = value; }
        }

        public DirectoryInfo DestinationDirectory
        {
            get { return _destinationDirectory; }
            set { _destinationDirectory = value; }
        }

        public bool MoveContent
        {
            get { return _moveContent; }
            set { _moveContent = value; }
        }

        public string SubdirectorySeparator
        {
            get { return _subdirectorySeparator; }
            set { _subdirectorySeparator = value; }
        }

        private void ProcessSourceDirectory()
        {
            ProcessSourceDirectory(this.MoveContent);
        }

        private void ProcessSourceDirectory(bool moveContent)
        {
            Flatten(this.SourceDirectory, this.DestinationDirectory, this.SubdirectorySeparator, moveContent);
        }

        private static bool Flatten(DirectoryInfo sourceDirectory, DirectoryInfo destinationDirectory, string subdirectorySeparator, bool moveContent)
        {
            if (!sourceDirectory.Exists)
            {
                throw new Exception(string.Format("The SourceDirectory '{0}' does not exist!", sourceDirectory.FullName));
            }

            //1. copy/move all the files that are within the source directory:
            FileInfo[] files = sourceDirectory.GetFiles();
            if (files != null && files.LongLength > 0 && string.Compare(sourceDirectory.FullName, destinationDirectory.FullName, true) != 0)
            {
                if (!destinationDirectory.Exists) destinationDirectory.Create();

                foreach (FileInfo file in files)
                {
                    string destinationFileName = Path.Combine(destinationDirectory.FullName, file.Name);
                    if (moveContent)
                    {
                        file.MoveTo(destinationFileName);
                    }
                    else
                    {
                        file.CopyTo(destinationFileName);
                    }
                }
            }

            //TODO
            //2. flatten all of the subdirectories that are within the source directory:

            throw new Exception("method not implemented!");
        }

        public DirectoryTreeFlattener(string sourceDirectoryPath)
            : this(sourceDirectoryPath, sourceDirectoryPath, " - ", false)
        {
        }

        public DirectoryTreeFlattener(string sourceDirectoryPath, string subdirectorySeparator)
            : this(sourceDirectoryPath, sourceDirectoryPath, subdirectorySeparator, false)
        {
        }

        public DirectoryTreeFlattener(string sourceDirectoryPath, string subdirectorySeparator, bool moveContent)
            : this(sourceDirectoryPath, sourceDirectoryPath, subdirectorySeparator, moveContent)
        {
        }

        public DirectoryTreeFlattener(string sourceDirectoryPath, string destinationDirectoryPath, string subdirectorySeparator)
            : this(sourceDirectoryPath, destinationDirectoryPath, subdirectorySeparator, false)
        {
        }

        public DirectoryTreeFlattener(string sourceDirectoryPath, string destinationDirectoryPath, string subdirectorySeparator, bool moveContent)
        {
            _sourceDirectory = new DirectoryInfo(sourceDirectoryPath);
            _destinationDirectory = new DirectoryInfo(destinationDirectoryPath);
            _subdirectorySeparator = subdirectorySeparator;
            _moveContent = moveContent;
        }

        #region Implicit ITool Members

        public static ToolType ToolType
        {
            get { return _toolType; }
        }

        public static string ToolName
        {
            get { return _name; }
        }

        public static string ToolDescription
        {
            get { return _description; }
        }

        #endregion Implicit ITool Members

        #region Explicit ITool Members

        ToolType ITool.ToolType
        {
            get { return ToolType; }
        }

        string ITool.ToolName
        {
            get {return ToolName; }
        }

        string ITool.ToolDescription
        {
            get { return ToolDescription; }
        }

        #endregion Explicit ITool Members
    }
}
